package com.ittianyu.bottomnavigationviewex.item;
/*
 * Copyright (C) 2021 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import ohos.agp.render.Canvas;
import ohos.agp.render.Paint;
import ohos.agp.render.Path;
import ohos.agp.utils.Color;
import ohos.agp.utils.Point;
import ohos.agp.utils.RectFloat;

public class ShapeBadgeItem extends BadgeItem<ShapeBadgeItem> {
    public static final int SHAPE_OVAL = 0;
    public static final int SHAPE_RECTANGLE = 1;
    public static final int SHAPE_HEART = 2;
    public static final int SHAPE_STAR_3_VERTICES = 3;
    public static final int SHAPE_STAR_4_VERTICES = 4;
    public static final int SHAPE_STAR_5_VERTICES = 5;
    public static final int SHAPE_STAR_6_VERTICES = 6;

    private int mShape = SHAPE_STAR_5_VERTICES;

    private int mShapeColor = Color.RED.getValue();

    private int mHeightInPixels;
    private int mWidthInPixels;
    private RectFloat mCanvasRect = new RectFloat();
    private Paint mCanvasPaint = new Paint();
    private Path mPath = new Path();

    public ShapeBadgeItem() {
        mCanvasPaint = new Paint();
        mCanvasPaint.setAntiAlias(true);
        mCanvasPaint.setStyle(Paint.Style.FILL_STYLE);
    }

    public ShapeBadgeItem setShape(int shape) {
        mShape = shape;
        return this;
    }

    public ShapeBadgeItem setShapeColor(int color) {
        mShapeColor = color;
        return this;
    }

    public ShapeBadgeItem setSizeInPixels(int heightInPx, int widthInPx) {
        mHeightInPixels = heightInPx;
        mWidthInPixels = widthInPx;
        return this;
    }

    private void drawStar(Canvas canvas, int numOfPt, float width, float height) {
        double section = 2.0 * Math.PI / numOfPt;
        double halfSection = section / 2.0d;
        double antiClockRotation = getStarAntiClockRotationOffset(numOfPt);

        float x = width / 2.0f;
        float y = height / 2.0f;
        float radius;
        float innerRadius;

        if (width > height) {
            radius = height * 0.5f;
            innerRadius = height * 0.25f;
        } else {
            radius = width * 0.5f;
            innerRadius = height * 0.25f;
        }

        mPath.reset();

        mPath.moveTo(
                (float) (x + radius * Math.cos(0 - antiClockRotation)),
                (float) (y + radius * Math.sin(0 - antiClockRotation)));
        mPath.lineTo(
                (float) (x + innerRadius * Math.cos(0 + halfSection - antiClockRotation)),
                (float) (y + innerRadius * Math.sin(0 + halfSection - antiClockRotation)));

        for (int i = 1; i < numOfPt; i++) {
            mPath.lineTo(
                    (float) (x + radius * Math.cos(section * i - antiClockRotation)),
                    (float) (y + radius * Math.sin(section * i - antiClockRotation)));
            mPath.lineTo(
                    (float) (x + innerRadius * Math.cos(section * i + halfSection - antiClockRotation)),
                    (float) (y + innerRadius * Math.sin(section * i + halfSection - antiClockRotation)));
        }

        mPath.close();

        canvas.drawPath(mPath, mCanvasPaint);
    }

    private double getStarAntiClockRotationOffset(int numOfPt) {
        if (numOfPt == 5) {
            return 2.0 * Math.PI / 20.0d;
        } else if (numOfPt == 6) {
            return 2.0 * Math.PI / 12.0d;
        }
        return 0;
    }

    private void drawHeart(Canvas canvas, float width, float height) {
        mPath.reset();

        // Starting point
        mPath.moveTo(width / 2, height / 5);

        // Upper left path
        mPath.cubicTo(new Point(5 * width / 14, 0), new Point(0, height / 15), new Point(width / 28, 2 * height / 5));

        // Lower left path
        mPath.cubicTo(
                new Point(width / 14, 2 * height / 3),
                new Point(3 * width / 7, 5 * height / 6),
                new Point(width / 2, height));

        // Lower right path
        mPath.cubicTo(
                new Point(4 * width / 7, 5 * height / 6),
                new Point(13 * width / 14, 2 * height / 3),
                new Point(27 * width / 28, 2 * height / 5));

        // Upper right path
        mPath.cubicTo(new Point(width, height / 15), new Point(9 * width / 14, 0), new Point(width / 2, height / 5));

        mPath.close();

        canvas.drawPath(mPath, mCanvasPaint);
    }

    @Override
    ShapeBadgeItem getSubInstance() {
        return this;
    }

    @Override
    public void drawToCanvas(
            Canvas canvas,
            float centerX,
            float centerY,
            float defaultOffsetX,
            float defaultOffsetY,
            int size,
            int padding) {
        if (!isSetOffset) {
            offsetX = defaultOffsetX;
            offsetY = defaultOffsetY;
        }
        if (mWidthInPixels == 0) {
            mWidthInPixels = size;
        }
        if (mHeightInPixels == 0) {
            mHeightInPixels = size;
        }
        mCanvasRect.left = 0;
        mCanvasRect.right = mWidthInPixels;
        mCanvasRect.top = 0;
        mCanvasRect.bottom = mHeightInPixels;
        mCanvasPaint.setColor(new Color(mShapeColor));
        canvas.save();
        canvas.translate(centerX + offsetX - mWidthInPixels / 2, centerY + offsetY - mHeightInPixels / 2);

        if (mShape == SHAPE_RECTANGLE) {
            canvas.drawRect(mCanvasRect, mCanvasPaint);
        } else if (mShape == SHAPE_OVAL) {
            canvas.drawOval(mCanvasRect, mCanvasPaint);
        } else if (mShape == SHAPE_STAR_3_VERTICES
                || mShape == SHAPE_STAR_4_VERTICES
                || mShape == SHAPE_STAR_5_VERTICES
                || mShape == SHAPE_STAR_6_VERTICES) {
            drawStar(canvas, mShape, mWidthInPixels, mHeightInPixels);
        } else if (mShape == SHAPE_HEART) {
            drawHeart(canvas, mWidthInPixels, mHeightInPixels);
        } else {
            canvas.drawCircle(
                    mWidthInPixels / 2,
                    mHeightInPixels / 2,
                    mWidthInPixels > mHeightInPixels ? mHeightInPixels / 2 : mWidthInPixels / 2,
                    mCanvasPaint);
        }
        canvas.restore();
    }
}
